﻿using System;
using System.Collections.Generic;
using System.Linq;
using Joel.Vishnu.Modelo.Entidades;
using Joel.Vishnu.Modelo.Enumeradores;
using Joel.Vishnu.Presentacion.Vistas;
using Joel.Vishnu.Presentacion;
using Joel.Vishnu.Modelo.Objetos;

namespace Joel.Vishnu.Consola
{
    public class Empleados : Base, IEmpleados
    {
        #region Constructores

        public Empleados()
            : base()
        {
            presentador = new EmpleadosPresentador(this);
            listaEmpleados = new List<Empleado>();
            validador = String.Empty;
        }

        #endregion

        #region Atributos

        private EmpleadosPresentador presentador;
        private Int32 empleadoId;
        private String nombre;
        private String apellido;
        private Int32 dni;
        private String telefono;
        private String direccion;
        private Int32 barrioId;
        private String email;
        private Int32 generoId;
        private DateTime fechaContratacion;
        private DateTime fechaCumpleanos;
        private Int32 estadoCivilId;
        private String contactoEmergenciaNombre;
        private String contactoEmergenciaTelefono;
        private Decimal salario;
        private EnumEstado estado;
        private List<Empleado> listaEmpleados;
        private String validador;

        #endregion

        #region Propiedades

        public Int32 EmpleadoId
        {
            get { return empleadoId; }
        }

        public String Nombre
        {
            get { return nombre; }
        }

        public String Apellido
        {
            get { return apellido; }
        }

        public Int32 Dni
        {
            get { return dni; }
        }

        public String Telefono
        {
            get { return telefono; }
        }

        public String Direccion
        {
            get { return direccion; }
        }

        public Int32 BarrioId
        {
            get { return barrioId; }
        }

        public List<Barrio> ListaBarrios
        {
            set { new NotImplementedException(); }
        }

        public String Email
        {
            get { return email; }
        }

        public Int32 GeneroId
        {
            get { return generoId; }
        }

        public DateTime FechaContratacion
        {
            get { return fechaContratacion; }
        }

        public DateTime FechaCumpleanos
        {
            get { return fechaCumpleanos; }
        }

        public Int32 EstadoCivilId
        {
            get { return estadoCivilId; }
        }

        public List<EstadoCivil> ListaEstadosCiviles
        {
            set { throw new NotImplementedException(); }
        }

        public String ContactoEmergenciaNombre
        {
            get { return contactoEmergenciaNombre; }
        }

        public String ContactoEmergenciaTelefono
        {
            get { return contactoEmergenciaTelefono; }
        }

        public Decimal Salario
        {
            get { return salario; }
        }

        public EnumEstado Estado
        {
            get { return estado; }
        }

        public List<Empleado> ListaEmpleados
        {
            set { listaEmpleados = value; }
        }

        private Barrios Barrios
        {
            get { return new Barrios(); }
        }

        private Generos Generos
        {
            get { return new Generos(); }
        }

        private EstadosCiviles EstadosCiviles
        {
            get { return new EstadosCiviles(); }
        }

        #endregion

        #region Metodos

        public String Menu()
        {
            Console.Clear();
            Titulo("********** Menú empleados **********");
            MensajeInformativo("(1) Agregar");
            MensajeInformativo("(2) Modificar");
            MensajeInformativo("(3) Eliminar");
            MensajeInformativo("(4) Listado");
            Console.WriteLine();
            MensajeInformativo("(5) Barrios");
            Console.WriteLine();
            MensajeInformativo("(0) Menú principal");
            Console.WriteLine();
            MensajeInformativo("Presione el número de la opción deseada.");
            return Console.ReadKey().KeyChar.ToString();
        }

        public void Insertar()
        {
            try
            {
                Console.Clear();
                Titulo("********** Agregar empleado **********");
                MensajeInformativoSeguido("Nombre: ");
                nombre = Console.ReadLine();
                MensajeInformativoSeguido("Apellido: ");
                apellido = Console.ReadLine();
                MensajeInformativoSeguido("DNI: ");
                validador = Console.ReadLine();
                if (Validadores.ValidadorEnteros(validador) == false)
                    throw new Exception("Sólo puede ingresar números para el DNI.");
                if (validador.Length < 8 || validador.Length > 8)
                    throw new Exception("El DNI debe ser de 8 dígitos.");
                dni = Convert.ToInt32(validador);
                MensajeInformativoSeguido("Teléfono: ");
                validador = Console.ReadLine();
                validador = validador.Replace("(", "");//TODO: Estos reemplazos para  el Telefono se podrian hacer en el metodo de validacion.
                validador = validador.Replace(")", "");
                validador = validador.Replace("-", "");
                validador = validador.Replace(" ", "");
                if (Validadores.ValidadorTelefonos(validador) == false)
                    throw new Exception("El número de teléfono debe estar compuesto de números enteros.");
                telefono = validador;
                MensajeInformativoSeguido("Dirección: ");
                direccion = Console.ReadLine();
                Barrios.MostrarBarrios();
                MensajeInformativoSeguido("Barrio Id: ");
                validador = Console.ReadLine();
                if (Validadores.ValidadorEnteros(validador) == false)
                    throw new Exception("El barrio Id debe ser un número entero.");
                barrioId = Convert.ToInt32(validador);
                MensajeInformativoSeguido("Email: ");
                email = Console.ReadLine();
                Generos.MostrarGeneros();
                MensajeInformativoSeguido("Género Id: ");
                validador = Console.ReadLine();
                if (Validadores.ValidadorEnteros(validador) == false)
                    throw new Exception("El género Id debe ser un número entero.");
                generoId = Convert.ToInt32(validador);
                MensajeInformativoSeguido("Fecha contratación: ");
                validador = Console.ReadLine();
                if (Validadores.ValidadorFechas(validador) == false)
                    throw new Exception("La fecha de contratación debe ser de formato MM/DD/AAAA.");
                fechaContratacion = Convert.ToDateTime(Console.ReadLine());
                MensajeInformativoSeguido("Fecha de cumpleaños: ");
                validador = Console.ReadLine();
                if (Validadores.ValidadorFechas(validador) == false)
                    throw new Exception("La fecha de cumpleaños debe ser de formato MM/DD/AAAA.");
                fechaCumpleanos = Convert.ToDateTime(validador);
                EstadosCiviles.MostrarEstadosCiviles();
                MensajeInformativoSeguido("Estado civil Id: ");
                validador = Console.ReadLine();
                if (Validadores.ValidadorEnteros(validador) == false)
                    throw new Exception("El estado civil Id debe ser un número entero.");
                estadoCivilId = Convert.ToInt32(validador);
                MensajeInformativoSeguido("Nombre de contacto emergencia: ");
                contactoEmergenciaNombre = Console.ReadLine();
                MensajeInformativoSeguido("Teléfono de contacto emergencia: ");
                validador = Console.ReadLine();
                validador = validador.Replace("(", "");//TODO: Estos reemplazos para  el Telefono se podrian hacer en el metodo de validacion.
                validador = validador.Replace(")", "");
                validador = validador.Replace("-", "");
                validador = validador.Replace(" ", "");
                if (Validadores.ValidadorTelefonos(validador) == false)
                    throw new Exception("El número de teléfono del contacto de emergencia debe estar compuesto de números enteros.");
                contactoEmergenciaTelefono = validador;
                MensajeInformativoSeguido("Salario: ");
                validador = Console.ReadLine();
                if (Validadores.ValidadorDecimales(validador) == false)
                    throw new Exception("Salario ingresado erroneamente.");
                salario = Convert.ToDecimal(validador);
                estado = EnumEstado.NUEVO;
                presentador.Aceptar();
                Console.WriteLine();
                MensajeInformativoSeguido("Empleado ingresado.");
                Console.ReadKey();
            }
            catch (Exception ex)
            {
                MensajeError(ex.Message);
            }
        }

        public void Modificar()
        {
            try
            {
                String textoInsertado = String.Empty;
                Empleado empleado = new Empleado();

                Console.Clear();
                Titulo("********** Modificar empleado **********");
                MostrarEmpleados();
                Console.WriteLine();
                MensajeInformativoSeguido("Seleccione Id: ");
                validador = Console.ReadLine();
                if (validador == String.Empty)
                    throw new Exception("Debe seleccionar un empleado.");
                empleadoId = Convert.ToInt32(validador);
                if (empleadoId == 1)
                    throw new Exception("No se puede modificar un empleado por defecto.");
                empleado = listaEmpleados.Where(x => x.Id == empleadoId).FirstOrDefault();

                MensajeInformativoSeguido("Nombre: ");
                textoInsertado = Console.ReadLine();
                if (textoInsertado != "=")
                    nombre = textoInsertado;
                else
                    nombre = empleado.Nombre;

                MensajeInformativoSeguido("Apellido: ");
                textoInsertado = Console.ReadLine();
                if (textoInsertado != "=")
                    apellido = textoInsertado;
                else
                    apellido = empleado.Apellido;

                MensajeInformativoSeguido("DNI: ");
                textoInsertado = Console.ReadLine();
                if (textoInsertado != "=")
                    dni = Convert.ToInt32(textoInsertado);
                else
                    dni = empleado.Dni;

                MensajeInformativoSeguido("Teléfono: ");
                textoInsertado = Console.ReadLine();
                if (textoInsertado != "=")
                    telefono = textoInsertado;
                else
                    telefono = empleado.Telefono;

                MensajeInformativoSeguido("Dirección: ");
                textoInsertado = Console.ReadLine();
                if (textoInsertado != "=")
                    direccion = textoInsertado;
                else
                    direccion = empleado.Direccion;

                Barrios.MostrarBarrios();
                MensajeInformativoSeguido("Barrio Id: ");
                textoInsertado = Console.ReadLine();
                if (textoInsertado != "=")
                    barrioId = Convert.ToInt32(textoInsertado);
                else
                    barrioId = empleado.Barrio.Id;

                MensajeInformativoSeguido("Email: ");
                textoInsertado = Console.ReadLine();
                if (textoInsertado != "=")
                    email = textoInsertado;
                else
                    email = empleado.Email;

                Generos.MostrarGeneros();
                MensajeInformativoSeguido("Género Id: ");
                textoInsertado = Console.ReadLine();
                if (textoInsertado != "=")
                    generoId = Convert.ToInt32(textoInsertado);
                else
                    generoId = empleado.Genero.Id;

                MensajeInformativoSeguido("Fecha de contratación: ");
                textoInsertado = Console.ReadLine();
                if (textoInsertado != "=")
                    fechaContratacion = Convert.ToDateTime(textoInsertado);
                else
                    fechaContratacion = empleado.FechaContratacion;

                MensajeInformativoSeguido("Fecha de cumpleaños: ");
                textoInsertado = Console.ReadLine();
                if (textoInsertado != "=")
                    fechaCumpleanos = Convert.ToDateTime(textoInsertado);
                else
                    fechaCumpleanos = empleado.FechaCumpleanos;

                EstadosCiviles.MostrarEstadosCiviles();
                MensajeInformativoSeguido("Estado civil Id: ");
                textoInsertado = Console.ReadLine();
                if (textoInsertado != "=")
                    estadoCivilId = Convert.ToInt32(textoInsertado);
                else
                    estadoCivilId = empleado.EstadoCivil.Id;

                MensajeInformativoSeguido("Nombre de contacto de emergencia: ");
                textoInsertado = Console.ReadLine();
                if (textoInsertado != "=")
                    contactoEmergenciaNombre = textoInsertado;
                else
                    contactoEmergenciaNombre = empleado.ContactoEmergenciaNombre;

                MensajeInformativoSeguido("Teléfono de contacto de emergencia: ");
                textoInsertado = Console.ReadLine();
                if (textoInsertado != "=")
                    contactoEmergenciaTelefono = textoInsertado;
                else
                    contactoEmergenciaTelefono = empleado.ContactoEmergenciaTelefono;

                MensajeInformativoSeguido("Salario: ");
                textoInsertado = Console.ReadLine();
                if (textoInsertado != "=")
                    salario = Convert.ToDecimal(textoInsertado);
                else
                    salario = empleado.Salario;

                estado = EnumEstado.MODIFICAR;
                presentador.Aceptar();
                Console.WriteLine();
                MensajeInformativoSeguido("Empleado modificado.");
                Console.ReadKey();
            }
            catch (Exception ex)
            {
                MensajeError(ex.Message);
            }
        }

        public void Eliminar()
        {
            try
            {
                Console.Clear();
                Titulo("********** Eliminar empleado **********");
                MostrarEmpleados();
                Console.WriteLine();
                MensajeInformativoSeguido("Seleccione Id: ");
                validador = Console.ReadLine();
                if (validador == String.Empty)
                    throw new Exception("Debe seleccionar un empleado.");
                empleadoId = Convert.ToInt32(validador);
                if (empleadoId == 1)
                    throw new Exception("No se puede eliminar un empleado por defecto.");
                presentador.Eliminar();
                Console.WriteLine();
                MensajeInformativoSeguido("Empleado eliminado.");
                Console.ReadKey();
            }
            catch (Exception ex)
            {
                MensajeError(ex.Message);
            }
        }

        public void Listado()
        {
            try
            {
                Console.Clear();
                Titulo("********** Listado de empleados **********");
                MostrarEmpleados();
                Console.ReadKey();
            }
            catch (Exception ex)
            {
                MensajeError(ex.Message);
            }
        }

        public void MostrarEmpleados()
        {
            MensajeInformativo(String.Format("{0} {1} {2} {3} {4} {5} {6} {7} {8} {9} {10} {11} {12} {13} {14}",
                ArmarLineaInversa("Id", 3),
                ArmarLinea("Nombre", 16),
                ArmarLinea("Apellido", 15),
                ArmarLinea("DNI", 8),
                ArmarLinea("Teléfono", 15),
                ArmarLinea("Dirección", 20),
                ArmarLinea("Barrio", 15),
                ArmarLinea("Email", 30),
                ArmarLinea("Género", 9),
                ArmarLinea("Contratación", 12),
                ArmarLinea("Cumpleaños", 10),
                ArmarLinea("Estado civil", 14),
                ArmarLinea("Nombre de contacto", 18),
                ArmarLinea("Teléfono de contacto", 20),
                ArmarLineaInversa("Salario", 9)));
            presentador.ActualizarEmpleados();
            foreach (var item in listaEmpleados)
                Console.WriteLine(String.Format("{0} {1} {2} {3} {4} {5} {6} {7} {8} {9} {10} {11} {12} {13} {14}",
                    ArmarLineaInversa(Convert.ToString(item.Id), 3),
                    ArmarLinea(item.Nombre, 15),
                    ArmarLinea(item.Apellido, 15),
                    ArmarLinea(Convert.ToString(item.Dni), 8),
                    ArmarLinea(item.Telefono, 15),
                    ArmarLinea(item.Direccion, 20),
                    ArmarLinea(item.Barrio.Nombre, 15),
                    ArmarLinea(item.Email, 30),
                    ArmarLinea(item.Genero.Nombre, 9),
                    ArmarLinea(item.FechaContratacion.ToString("d"), 12),
                    ArmarLinea(item.FechaCumpleanos.ToString("d"), 10),
                    ArmarLinea(item.EstadoCivil.Nombre, 14),
                    ArmarLinea(item.ContactoEmergenciaNombre, 18),
                    ArmarLinea(item.ContactoEmergenciaTelefono, 20),
                    ArmarLineaInversa(item.Salario.ToString("C2"), 9)));
        }

        #endregion
    }
}
